package com.daka.controller;

import com.alibaba.fastjson.JSONObject;
import com.daka.entity.User;
import com.daka.enumerate.SpecialUrl;
import com.daka.enumerate.SpecialUrlType;
import com.daka.enumerate.StatusCode;
import com.daka.exception.ServiceRuntimeException;
import com.daka.service.UserService;
import com.daka.tools.AuctionEndLine;
import com.daka.tools.ConfigUtil;
import com.daka.tools.DateUtil;
import com.daka.tools.wechatPay.*;
import com.daka.vo.DataResponseVo;
import com.daka.vo.request.UrlRequestVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/index")
@Slf4j
public class IndexController {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private UserService userService;

    private final static String WEI_XIN_BROWSER = "micromessenger/";

    /**
     * 获取微信签名
     *
     * @param param 需要签名的页面
     * @return 签名信息
     */
    @RequestMapping(method = RequestMethod.POST, value = "/getWeChatJsSign")
    @ResponseBody
    public DataResponseVo<JSONObject> getWeChatJsSign(@RequestBody UrlRequestVo param) {

        if (StringUtils.isEmpty(param.getUrl())) {
            return new DataResponseVo<>(StatusCode.COMMON_PARAM_ERROR.getCode(), "输入参数异常");
        }


        String accessToken = redisTemplate.opsForValue().get("wxAccessToken");
        if (StringUtils.isBlank(accessToken)) {
            Token token = WechatUtil.token(ConfigUtil.getWxAppId(), ConfigUtil.getWxSecret());

            if (token == null || token.getAccess_token() == null) {
                return new DataResponseVo<>(StatusCode.SERVER_EXCEPTION.getCode(), "token获取异常");
            }

            accessToken = token.getAccess_token();

            redisTemplate.opsForValue().set("wxAccessToken", accessToken);
            redisTemplate.expire("wxAccessToken", 3600, TimeUnit.SECONDS);

        }

        Ticket ticket = WechatUtil.ticketGetticket(accessToken);

        String jsTiket = ticket.getTicket();
        String json = JsUtil.generateConfigJson(jsTiket, false, ConfigUtil.getWxAppId(), param.getUrl(), "showOptionMenu", "hideOptionMenu", "hideMenuItems", "closeWindow", "chooseWXPay", "scanQRCode", "onMenuShareTimeline", "onMenuShareAppMessage", "openLocation", "getLocation");
        JSONObject jsonObject = JSONObject.parseObject(json);
        log.info("/IndexController/getWeChatJsSign, responseJson" + jsonObject);
        return new DataResponseVo<>(StatusCode.OK.getCode(), jsTiket, jsonObject);
    }

    /**
     * 初始入口 通过这个接口获取openId
     *
     * @param request  http请求
     * @param response HttpResponse
     */
    @RequestMapping(method = RequestMethod.GET, value = "/indexPage")
    @ResponseBody
    public void indexSilent(HttpServletRequest request, HttpServletResponse response) {
        String paramString = request.getQueryString();
        Map<String, String[]> requestParameterMap = request.getParameterMap();
        log.info("/IndexController/indexPage, paramString" + paramString);
        String userAgent = request.getHeader("user-agent").toLowerCase();
        log.info("/IndexController/indexPage, userAgent : " + userAgent);

        try {
            //微信浏览器
            if ((userAgent.indexOf(WEI_XIN_BROWSER.toLowerCase()) > 0)) {

                log.info("/IndexController/indexPage, wei xin browser" + paramString);

                String callbackUrl = "/index/indexCb";
                if (requestParameterMap.get("type") != null && SpecialUrl.getByType(requestParameterMap.get("type")[0]) != null) {
                    callbackUrl = SpecialUrl.getByType(requestParameterMap.get("type")[0]).getCallbackUrl();
                }
                String wechatUrl = ConfigUtil.getRootUrl();

                String redirectUrl = WechatUtil.getWXOauthPageApi(ConfigUtil.getWxAppId(), wechatUrl
                        + callbackUrl + "?" + URLEncoder.encode(paramString, "UTF-8"), "snsapi_userinfo");
                response.sendRedirect(redirectUrl);
            } else { //其他浏览器
                log.info("/IndexController/indexPage, not wei xin browser");
            }
        } catch (IOException e) {
            throw new ServiceRuntimeException(StatusCode.SERVER_EXCEPTION.getCode(), "Confront problem at /index/indexPage");
        }

    }

    /**
     * 获取OpenId的微信服务器回调接口
     *
     * @param request  http请求
     * @param response httpResponse
     */
    @RequestMapping(method = RequestMethod.GET, value = "/indexCb")
    @ResponseBody
    public void indexSilentCb(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String[]> requestParameterMap = request.getParameterMap();
        String paramString = "";
        try {
            paramString = URLDecoder.decode(request.getQueryString(), "UTF-8");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        if (requestParameterMap.get("code") == null) {
            throw new ServiceRuntimeException(StatusCode.SERVER_EXCEPTION.getCode(), "微信授权失败");
        }
        String code = requestParameterMap.get("code")[0];

        log.info("/IndexController/indexcb, param : " + paramString);
        HashMap<String, String> hashMap = WechatUtil.getOpenId(ConfigUtil.getWxAppId(), ConfigUtil.getWxSecret(), code);
        log.info("/IndexController/indexcb, Hash : " + hashMap);
        String openId = null;
        String token = null;
        Long userId = 0l;

        if ((hashMap != null ? hashMap.get("openid") : null) != null && hashMap.get("token") != null) {
            openId = hashMap.get("openid");
            token = hashMap.get("token");
            log.info("/IndexController/indexcb, openId : " + openId + ", token : " + token);

            //获取用户信息时使用 start
            if (requestParameterMap.get("type") != null && SpecialUrl.getByType(requestParameterMap.get("type")[0]) != null) {

                if (Objects.equals(requestParameterMap.get("type")[0], SpecialUrl.PAY_URL.getType())) {
                    org.json.JSONObject jsonObject = WechatUtil.getUserBySNS(openId, token);

                    userId = Long.parseLong(requestParameterMap.get("userId")[0]);

                    User user = userService.selectById(userId);
                    if (StringUtils.isEmpty(user.getHeadUrl())) {
                        try {
                            UserInfo userInfo = new UserInfo();
                            userInfo.setHeadimgurl(jsonObject.getString("headimgurl"));
                            userService.saveWX(userInfo, userId);
                        } catch (JSONException e) {
                            log.info("获取用户图片错误");
                            e.printStackTrace();
                        }

                    }
                } else if (Objects.equals(requestParameterMap.get("type")[0], SpecialUrl.AUCTION_URL_INDEX.getType()) ||
                        Objects.equals(requestParameterMap.get("type")[0], SpecialUrl.AUCTION_URL_GOODS.getType())) {
                    org.json.JSONObject jsonObject = WechatUtil.getUserBySNS(openId, token);
                    try {
                        Cookie cookie = new Cookie("userHeadUrl", jsonObject.getString("headimgurl"));
                        cookie.setMaxAge(60 * 60 * 24 * 365);
                        cookie.setPath("/");
                        response.addCookie(cookie);
                    } catch (JSONException e) {
                        log.info("获取用户图片错误");
                        e.printStackTrace();
                    }
                }
            }

            //获取用户信息时使用 end

        }
        log.info("/IndexController/indexcb, openId : " + openId);
        if (!StringUtils.isEmpty(openId)) {
            Cookie cookie = new Cookie("newOpenId", openId);
            cookie.setMaxAge(60 * 60 * 24 * 365);
            cookie.setPath("/");
            response.addCookie(cookie);
        }
        if (!StringUtils.isEmpty(token)) {
            Cookie cookie = new Cookie("accessToken", token);
            cookie.setMaxAge(60 * 60 * 24 * 365);
            cookie.setPath("/");
            response.addCookie(cookie);
        }
        try {
            String wechatUrl = ConfigUtil.getRootUrl();

            String redirectStr = "/static/index.html";
            if (requestParameterMap.get("type") != null && SpecialUrl.getByType(requestParameterMap.get("type")[0]) != null) {
                redirectStr = SpecialUrl.getByType(requestParameterMap.get("type")[0]).getRedirectUrl();
            }
            String redirectUrl;
            if (Objects.equals(requestParameterMap.get("type")[0], SpecialUrlType.PAY_URL.getType()) ||
                Objects.equals(requestParameterMap.get("type")[0], SpecialUrlType.PAY_ONLY_URL.getType())) {

                redirectUrl = wechatUrl + redirectStr.replace("{?1}", requestParameterMap.get("projectName")[0]);
                redirectUrl = redirectUrl.replace("{?2}", requestParameterMap.get("money")[0]);
                redirectUrl = redirectUrl.replace("{?3}", userId.toString());
                redirectUrl = redirectUrl.replace("{?4}", requestParameterMap.get("orderCode")[0]);

                log.info("/IndexController/indexcb, redirectUrl" + redirectUrl);

                /*
                微信中不能用get或者post向第三方发起请求  微信服务器与自己服务器的所有交互全都是依赖于重定向的。
                */
//                HttpInvoker.httpGet(redirectUrl);

                response.sendRedirect(redirectUrl);

            } else {
                redirectUrl = wechatUrl + redirectStr;
                log.info("/IndexController/indexcb, redirectUrl" + redirectUrl + "?" + paramString);
                response.sendRedirect(redirectUrl + "?" + paramString);
            }

        } catch (IOException e) {
            throw new RuntimeException("Confront problem at getOpenIdStepTwo");
        }
    }

    /**
     * 截止时间
     */
    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, value = "/timeEndLine", consumes = "application/json")
    public DataResponseVo<Long> timeEndLine() {

        Long thisTime = new Date().getTime();
        Long endTime = DateUtil.str2Date(AuctionEndLine.AUCTION_END_TIME, DateUtil.DATETIME_YYYY_MM_DD_HH_MM_SS).getTime();

        return new DataResponseVo<>(StatusCode.OK.getCode(), StatusCode.OK.getMessage(), BigDecimal.valueOf(endTime - thisTime).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_DOWN).longValue());
    }

    /**
     * 测试接口  给定一个openId
     *
     * @param response httpResponse
     */
    @RequestMapping(method = RequestMethod.GET, value = "/test")
    @ResponseBody
    public void setTestOpenId(HttpServletResponse response) {
        // Set a fake openId for dev purpose
        String openId = "oNcrgvpKHJOeyrF-3DjXCND6KF3k";
        Cookie cookie = new Cookie("newOpenId", openId);
        cookie.setMaxAge(60 * 60 * 24 * 3);
        cookie.setPath("/");
        response.addCookie(cookie);
        try {
            response.sendRedirect("/static/index.html?ngoCode=GV0000076919");
        } catch (IOException e) {
            throw new RuntimeException("Confront problem at getOpenIdStepTwo");
        }
    }
}